<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>SoundManager 2: JavaScript Sound For The Web</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<!-- the SoundManager 2 API -->
<script type="text/javascript" src="script/soundmanager2.js"></script>
</head>

<script type="text/javascript">
function getStyle(el){
	return window.getComputedStyle ? getComputedStyle(el, '') : el.currentStyle;
}

function wheelDeltaValue( e ){
	if (e.wheelDelta) {
		var delta = e.wheelDelta/120; 
		if (window.opera) delta = -delta;
	} else if (e.detail) {
		delta = -e.detail/3;
	}
	return delta;
}
//-------------------------------
function fixEvent(e) {
e = e || window.event;

if (!e.target) e.target = e.srcElement;

if (e.pageX == null && e.clientX != null ) { // если нет pageX..
var html = document.documentElement;
var body = document.body;

e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);
e.pageX -= html.clientLeft || 0;

e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);
e.pageY -= html.clientTop || 0;
}

if (!e.which && e.button) {
e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) )
}

return e;
}

var addEvent, removeEvent;
if (document.addEventListener) { // проверка существования метода
addEvent = function(elem, type, handler, capture) {
	elem.addEventListener(type, handler, capture ? true : false)
}
removeEvent = function(elem, type, handler, capture) {
	elem.removeEventListener(type, handler, capture ? true : false)
}
} else {
	addEvent = function(elem, type, handler) {

		var scope = elem._listeners || {},
		listeners = scope[ type ] = scope[ type ] || [],
		proxy = function() {
			handler.call( elem, window.event );
		}

		listeners[ listeners.length ] = {
			original: handler,
			proxy: proxy
		}
		elem._listeners = scope;

		elem.attachEvent("on" + type, proxy);
	}
	removeEvent = function(elem, type, handler) {

		var scope = elem._listeners || {},
		listeners = scope[ type ] || [];

		for( var i = listeners.length - 1; i >= 0; i-- ) {
			if ( listeners[ i ].original === handler ) {
				elem.detachEvent( "on" + type, listeners[ i ].proxy );
				listeners.splice( i, 1 );
				break;
			}
		}
	}
}

//--------------------------------
function getCoords(element) {
var box = element.getBoundingClientRect();

var body = document.body;
var docElem = document.documentElement;

var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;

var clientTop = docElem.clientTop || body.clientTop || 0;
var clientLeft = docElem.clientLeft || body.clientLeft || 0;

var top  = box.top +  scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;

return { top: Math.round(top), left: Math.round(left) };
}

function setDraggble( elem, options, onDragStart, onDrag, onDragEnd ) {
	var opt = options || {},
		handle = opt.handle || elem
	, onDragStart = onDragStart || null
	, onDrag = onDrag || null
	, onDragEnd = onDragEnd || null;

	var mousedown = function(e) {
	var self = this;
	e = fixEvent(e); 

	var coords = getCoords(this);
	var coordsP = getCoords(this.parentNode);
	var shiftX = e.pageX - coords.left + coordsP.left;
	var shiftY = e.pageY - coords.top + coordsP.top;

	this.style.position = 'absolute';
	if(typeof onDragStart =="function") onDragStart();

	this.style.zIndex = 1000; // над другими элементами

	function moveAt(e) {
	var oldLeft = parseInt(self.style.left), oldTop = parseInt(self.style.top);
	if( !opt.onlyVertical ) self.style.left = e.pageX - shiftX + 'px';
	if( !opt.onlyHorizontal ) self.style.top = e.pageY - shiftY+ 'px';
	return { shiftLeft: (e.pageX - shiftX)-oldLeft, shiftTop: (e.pageY - shiftY)-oldTop };
	}

	documentMousemove = function(e) {
	e = fixEvent(e);
	shiftEl = moveAt(e); /* сдвиг элемента */
	if(typeof onDrag =="function") onDrag( shiftEl );	
	};
	addEvent( document, 'mousemove', documentMousemove );

	documentMouseup = function() {
	removeEvent( document, 'mousemove', documentMousemove );
	removeEvent( document, 'mouseup', documentMouseup );
	if(typeof onDragEnd =="function") onDragEnd( shiftEl );
	};
	addEvent( document, 'mouseup', documentMouseup );

	if( e.preventDefault )  e.preventDefault();
	else e.returnValue = false;	
	}
	addEvent( elem, 'mousedown', mousedown );

	elem.ondragstart = function() { 
	return false; 
	};
}
//--------------------------
function addClass(elem, clazz) {
  var c = elem.className.split(' ');
  for(var i=0; i<c.length; i++) {
    if (c[i] == clazz) return;
  }

  if (elem.className == '') elem.className = clazz;
  else elem.className += ' ' + clazz;
}

function removeClass(elem, clazz) {
  var c = elem.className.split(' ');
  for(var i=0; i<c.length; i++) {
    if (c[i] == clazz) c.splice(i--, 1);
  }

  elem.className = c.join(' ');
}

function hasClass(el, cls) {
  for(var c = el.className.split(' '),i=c.length-1; i>=0; i--) {
    if (c[i] == cls) return true;
  }
  return false;
}

//------------------
function msToTime( ms ){
	var day = parseInt(ms/(60*60*1000*24)),
		hour = parseInt(ms/(60*60*1000))%24,
		min = parseInt(ms/(1000*60))%60,
		sec = parseInt(ms/1000)%60,
		res = {day:day,hour:hour,min:min,sec:sec};
	//если полученное число меньше 10 дописываем 0
	for(var key in res) if( res[key]<10 ) res[key]='0'+res[key];
	
	return res;
}			

</script>

<style type="text/css">
.clear_both{
	clear:both;
}
#playerDiv{
	width: 180px;
	padding: 3px;
}
#loadingline{
	background-color: #999;
	width: 0%;
	height: 100%;
}
#timeline, #volumeline{
	position:relative;
	height: 10px;
	background-color:#999;
}
#timeline{
	width: 140px;
	height: 5px;
	margin: 10px 0 0 3px;
	background-color:#CCC;
}
#volumeDiv{
	float: right;
	width: 30px;
}
#volumeline{
	width: 5px;
	height: 44px;
	margin: 3px 0 2px 13px;
}
	#positionslider, #volumeslider{
		position:absolute;
		background-color:#CCC;
		cursor: pointer;
		border-radius:5px;
	}
	#positionslider{
		width: 7px;
		height: 20px;
		top: -7px;
	}
	#volumeslider{
		width: 20px;
		height: 7px;
		left: -7px;	
	}
	
.info{
	text-align: center;
}
#info_position_duration{
	padding-top: 8px;
}


.playlist_list{
	width: 99%;
	box-sizing: border-box;
	position:absolute;
	list-style-type: none;
	padding: 0; margin: 0;
}
	.playlist_list li{
		
	}
.playlist_item{
		display: inline-block;
		width: 97%;
		zoom: 1;
		cursor: pointer;
		padding: 3px;
		border-radius:5px;
		border: solid 1px #999;
}
	.playlist_item.active, .playlist_item:hover{
		background-color: skyblue;
	}
.titleEllipsis{
	float: left;
	width: 85%;
	text-overflow: ellipsis;
	white-space: nowrap;
	overflow: hidden;
}	

#playlist_cont{
	height: 200px;
	width: 425px;
	padding: 3px;
	overflow: auto;
	position:relative;
}
</style>

<div id="playerDiv">
	<div id="volumeDiv">
		<div id="volumeline">
			<div id="volumeslider"></div>
		</div>
		<div class="info" id="info_volume">100</div>	
	</div>
	
	<button onclick="playListPlay( playList, -1 );"><b>&lt;&lt;</b></button>

	<button id="playPauseButton" onclick="mySound.playPause()">&#9658;</button>
	<button onclick="mySound.stop()">&#8718;</button>

	<button onclick="playListPlay( playList, 1 );"><b>&gt;&gt;</b></button>
	
	<div id="timeline">
		<div id="loadingline"></div>
		<div id="positionslider"></div>
		<div class="info" id="info_position_duration"> 00:00 </div>	
	</div>
	<div class="clear_both"></div>
</div>
		
<button onclick="playListArm( plist );">&#9745;</button>
<button onclick="playListArm( plist1 );">&#9745;</button>

<div class="" id="playlist_cont"></div>		


<script type="text/javascript">
var mySound, createSound;

soundManager.setup({
  url: '/sm2/swf/',
  onready: function() {
    
	createMySound = function( url ){
		
		var idS = 'aSound',// убиваем предыдущий
			prev = soundManager.getSoundById( idS );
		if(prev!=undefined) prev.destruct();
  
		var obj = soundManager.createSound({
			id: idS,
			url: url,

			onplay: function(){ upViewFunc( this ) },// callback for "play" start
			onstop: function(){ this.setPosition(0); upViewFunc( this ) },// callback for "user stop"
			onpause: function(){ upViewFunc( this ) },// callback for "pause"
			onresume: function(){ upViewFunc( this ) }, 

			whileplaying: function(){ upViewFunc( this ) }, 
			
			whileloading: function(){ upViewFunc( this ) }, 

			onfinish: function(){ // callback function for "sound finished playing"
				setTimeout(function(){
					if( playList.curent == playList.list.length-1 ){
					
					}
					else 
					playListPlay( playList, 1 );
					
					upViewFunc( mySound );					
				},0);

			} 
		});
		
		obj.playPause = function(){ 
			if ( this.paused ) 
				this.resume();
			else
			if ( this.playState == 1 ) //1 = playing or buffering sound; 0 = stopped/uninitialised
				this.pause();
			else this.play();
		};
		
		obj.setValue = function( prop, value ){
			switch (prop){
				case 'pan':
				this.setPan(value);
				break;
				case 'position':
				this.setPosition(value);
				break;
				case 'volume':
				this.setVolume(value);
				break;				
			};
			
			upViewFunc( this );
		};
	
		return obj;
	};
	

	playListArm( plist );

  },//onready
  ontimeout: function() {
    // Hrmm, SM2 could not start. Missing SWF? Flash blocked? Show an error, etc.?
  }
});


var playerDiv = document.getElementById( 'playerDiv' ),
	playPauseButton = document.getElementById( 'playPauseButton' ),
	positionslider = document.getElementById( 'positionslider' ),
	volumeslider = document.getElementById( 'volumeslider' ),
	volumeline = document.getElementById("volumeline"),
	loadingline = document.getElementById("loadingline"),
	positionsliderPressed = volumesliderPressed = false,
	
	timelineWidth = parseInt(getStyle(document.getElementById("timeline")).width),
	volumelineHeight = parseInt(getStyle(volumeline).height),
	
	info_position_duration = document.getElementById( 'info_position_duration' ),
	info_volume = document.getElementById( 'info_volume' )
	;
	


setDraggble( positionslider, 
	{onlyHorizontal:1},
	function(){ positionsliderPressed = true }, 
	function(){
		if(!positionsliderPressed) return;

		var x =parseInt( getStyle(positionslider).left ),
			sliderWidth = parseInt( getStyle(positionslider).width );
		var minValue = 0;
		
		x = Math.min( timelineWidth-sliderWidth, Math.max(minValue, x) );
		positionslider.style.left = x+'px';
		
		if( !mySound.duration ) return;
		var position = Math.round( mySound.duration*( (x-minValue)/(timelineWidth-minValue-sliderWidth) ) );
		//console.log( positionslider.style.left+'; '+position+'; '+mySound.duration);
		
		mySound.setPosition( position );
		upViewFunc( mySound );	
	}, 
	function(){ positionsliderPressed = false} 
);//, onDragStart, onDrag, onDragEnd
setDraggble( volumeslider, 
	{onlyVertical:1},
	function(){ volumesliderPressed = true }, 
	function(){
		if(!volumesliderPressed) return;

		var y =parseInt( getStyle(volumeslider).top ),
			sliderHeight = parseInt( getStyle(volumeslider).height );
		var minValue = 0;
		
		y = Math.min( volumelineHeight-sliderHeight, Math.max(minValue, y) );
		volumeslider.style.top = y+'px';
		
		if( !mySound.setVolume ) return;
		var volume = 100 - Math.round( 100 *( (y-minValue)/(volumelineHeight-minValue-sliderHeight) ) );
		
		mySound.setVolume( volume );
		upViewFunc( mySound );		
	}, 
	function(){ volumesliderPressed = false} 
);

playerDiv.onmousewheel = function(e) {
	e = fixEvent(e);

	var y =( parseInt( getStyle(volumeslider).top ) || 0 ) - wheelDeltaValue( e )*5,
		sliderHeight = parseInt( getStyle(volumeslider).height );
	var minValue = 0;
	
	y = Math.min( volumelineHeight-sliderHeight, Math.max(minValue, y) );
	volumeslider.style.top = y+'px';
	
	if( !mySound.setVolume ) return;
	var volume = 100 - Math.round( 100 *( (y-minValue)/(volumelineHeight-minValue-sliderHeight) ) );
	
	mySound.setVolume( volume );
	upViewFunc( mySound );	
	
	event.preventDefault? event.preventDefault():event.returnValue = false;
}

	
// обновление интерфейса, вывод информации
function upViewFunc( smObj ){
	//кнопка play/pause
	playPauseButton.innerHTML = smObj.playState==0 || smObj.paused ? '&#9658;' : '&#9646;&#9646;';
	//позиция
	var sliderWidth = parseInt(getStyle(positionslider).width),
		minValue = 0,
		sliderPosition = minValue + Math.round((timelineWidth - minValue - sliderWidth) * smObj.position / smObj.duration);
	sliderPosition = Math.min( timelineWidth-sliderWidth, Math.max(minValue, sliderPosition) );
	positionslider.style.left = sliderPosition+"px";
	//громкость
		sliderHeight = parseInt(getStyle(volumeslider).height),
		minValue = 0,
		sliderPosition = minValue + Math.round((volumelineHeight - minValue - sliderHeight) * smObj.volume / 100);
	sliderPosition = (volumelineHeight-sliderHeight) - Math.min( volumelineHeight-sliderHeight, Math.max(minValue, sliderPosition) );
	volumeslider.style.top = sliderPosition+"px";
	
	loadingline.style.width = Math.round(100 * (smObj.bytesLoaded/smObj.bytesTotal) )+'%';
	loadingline.setAttribute('title', (smObj.bytesTotal/1024/1024).toFixed(2)+'mb')
	
	//вывод данных
		//позиция:
	var position= smObj.position || 0,
		t = msToTime( position ), d = msToTime( smObj.duration ),
		bt = msToTime( smObj.duration - position ); 	
	info_position_duration.innerHTML = (t.hour!='00'?t.hour:'')+t.min+':'+t.sec+'/'+
		(d.hour!='00'?d.hour:'')+d.min+':'+d.sec+' (-'+
		(bt.hour!='00'?bt.hour:'')+bt.min+':'+bt.sec+')';
		//громкость
	info_volume.innerHTML = smObj.volume;	
	
};
</script>

<script type="text/javascript">

var plist1={
	 presrc:'http://cs4755.userapi.com/u96933015/audios/'
	,pretitle:'Harrison Harry – Fantasticheskaya.Saga part '
	,list:{
0:{src:'fa7325529a72.mp3',title:'1 Harrison Harry – Fantasticheskaya.Saga part',dur:'0:27'},
1:{src:'bd0b78d61f19.mp3',title:'2',dur:'5:38'},
2:{src:'356aa04085ae.mp3',title:'3',dur:'5:14'},
3:{src:'9dfb188e028d.mp3',title:'4',dur:'6:10'},
4:{src:'6f472840a37d.mp3',title:'5',dur:'8:11'},
5:{src:'7aa0b6c1587b.mp3',title:'6',dur:'7:48'},
6:{src:'14b2025687cb.mp3',title:'7',dur:'4:36'},
7:{src:'d716bda2f709.mp3',title:'8',dur:'5:42'},
8:{src:'f7deaf457dad.mp3',title:'9',dur:'6:12'},
9:{src:'84c2fce01b24.mp3',title:'10',dur:'7:36'},
10:{src:'25fd80e0eae4.mp3',title:'11',dur:'7:09'},
11:{src:'9e60b46ba365.mp3',title:'12',dur:'7:58'},
12:{src:'80dc2ef549ad.mp3',title:'13',dur:'5:21'},
13:{src:'efa45d0d0adc.mp3',title:'14',dur:'5:05'},
14:{src:'9d1d67094d7a.mp3',title:'15',dur:'4:56'},
15:{src:'5b2716fc4409.mp3',title:'16',dur:'7:06'},
16:{src:'8e70315e3963.mp3',title:'17',dur:'6:26'},
17:{src:'91e9a8fb5daf.mp3',title:'18',dur:'6:27'},
18:{src:'bf3f4e1eafce.mp3',title:'19',dur:'8:44'},
19:{src:'e77dc21090c6.mp3',title:'20',dur:'9:43'},
20:{src:'36f8685e5793.mp3',title:'21',dur:'8:17'},
21:{src:'bc18d4987981.mp3',title:'22',dur:'6:44'},
22:{src:'2a142ab2edc5.mp3',title:'23',dur:'8:16'},
23:{src:'286c87fea2aa.mp3',title:'24',dur:'8:13'},
24:{src:'2b0c0b4ab64e.mp3',title:'25',dur:'5:41'},
25:{src:'fe28cd4a2b8f.mp3',title:'26',dur:'4:42'},
26:{src:'ca9cf7349a9d.mp3',title:'27',dur:'5:35'},
27:{src:'46313202d25c.mp3',title:'28',dur:'7:41'},
28:{src:'bb456d1d8980.mp3',title:'29',dur:'9:20'},
29:{src:'c075d4020bb4.mp3',title:'30',dur:'7:47'},
30:{src:'238108784d6a.mp3',title:'31',dur:'6:55'},
31:{src:'8c7f50153968.mp3',title:'32',dur:'8:38'},
32:{src:'8bb372928faa.mp3',title:'33',dur:'8:06'},
33:{src:'ee082485d66b.mp3',title:'34',dur:'8:05'},
34:{src:'3543b259c8a7.mp3',title:'35',dur:'7:03'},
35:{src:'4706aa6907a7.mp3',title:'36',dur:'9:20'},
36:{src:'c0e05f3e48a4.mp3',title:'37',dur:'8:52'},
37:{src:'f2f85fe17d17.mp3',title:'38',dur:'7:24'},
38:{src:'cab6cbcbdf6b.mp3',title:'39',dur:'7:26'},
39:{src:'6ed6a2b7f6dd.mp3',title:'40',dur:'8:32'},
40:{src:'6e41dca65bfc.mp3',title:'41',dur:'7:19'},
41:{src:'df3719373394.mp3',title:'42',dur:'8:15'},
42:{src:'40eea7af56c5.mp3',title:'43',dur:'7:25'},
43:{src:'b90bad993d86.mp3',title:'44',dur:'7:29'},
44:{src:'fce6a8e75995.mp3',title:'45',dur:'7:15'},
45:{src:'e42f5b604701.mp3',title:'46',dur:'4:19'},
46:{src:'c5e71c00e78b.mp3',title:'47',dur:'7:09'},
47:{src:'2dab537972df.mp3',title:'48',dur:'6:07'},
48:{src:'23681f3726dc.mp3',title:'49',dur:'8:49'},
49:{src:'69f7716c0960.mp3',title:'50',dur:'9:20'},
50:{src:'84f10e212e30.mp3',title:'51',dur:'8:58'},
51:{src:'d7e103a596b7.mp3',title:'52',dur:'6:47'},
52:{src:'769ef699a307.mp3',title:'53',dur:'8:26'},
53:{src:'49f2b7dbb1c5.mp3',title:'54',dur:'5:40'},
54:{src:'88cde456e4ca.mp3',title:'55',dur:'8:06'},
55:{src:'2276e6d3b134.mp3',title:'56',dur:'6:48'},
56:{src:'b7816d555c0a.mp3',title:'57',dur:'5:29'},
57:{src:'dbb9da91976e.mp3',title:'58',dur:'8:24'}
	}			
};

var plist={
	 presrc:'http://cs5401.userapi.com/u127180798/audios/'
	,pretitle:'А. и Б. Стругацкие  – "Улитка на склоне" ч.'
	,list:{
		0:{src:'319b20998482.mp3',title:'1',dur:'34:16'},
		1:{src:'8eb364d4101d.mp3',title:'2',dur:'28:09'},
		2:{src:'bd6a92298b6c.mp3',title:'4',dur:'33:49'},
		3:{src:'2099112c7eb9.mp3',title:'3',dur:'31:26'},
		4:{src:'6a76876450a5.mp3',title:'5',dur:'31:57'}
	}			
};

			
var playList = {
	curent: null,
	list: null
	,listClassName: 'playlist_list'
	,itemClassName: 'playlist_item'
	,load: function( plistObj ){
		this.list = [];
		var list = plistObj.list;
		for(var k in list){
			var src = ( plistObj.presrc ? plistObj.presrc :'' )+list[k].src,
				title = ( plistObj.pretitle ? plistObj.pretitle :'' )+list[k].title,
				dur = list[k].dur;
			this.list.push( {src:src, title:title, dur:dur} );
		}
		this.curent	= 0;
		mySound = createMySound( this.list[ this.curent ].src );
	}
	,getListHtml: function(){
		var lis='', item;
		for(var i=0; i<this.list.length; i++){
			item = this.list[i];
			lis+='<li><div class="'+this.itemClassName+'" onclick="" id="'+this.itemClassName+'_'+i+'">'+
				'<div class="titleEllipsis" title="'+item.title+'">'+item.title+'</div>'+
				'<div style="float: right;">'+item.dur+'</div>'+
			'</div></li>';
		}
		return '<ul class="'+this.listClassName+'" id="'+this.listClassName+'">'+lis+'</ul>';
	}
	,listItemActivate: function(){
		var pList = this,
			its = document.getElementsByClassName( this.itemClassName );
		for(var i=0; i<its.length; i++){
			addEvent( its[i], 'click', function(){
				var ind = this.id.split('_').pop();
				playListPlay( pList, 0, ind );
			} );
		}
	}
	,listItemSetActive: function( ind ){
		var its = document.getElementsByClassName( this.itemClassName );
		if(its.length<1) return;
		
		for(var i=0; i<its.length; i++) removeClass( its[i], 'active' );
		var el = document.getElementById( this.itemClassName+'_'+ind ),
			elH = parseInt( el.parentNode.offsetHeight );//getStyle(el).height
		addClass( el, 'active' ); 
		document.getElementById( 'playlist_list' ).parentNode.scrollTop = ind*elH;
	}
}

function playListArm( plist ){
	if(mySound!=null && mySound.playState==1)
		if(!confirm('Прервать воспроизведение?')) return;
	
	playList.load( plist );
	//out playlist
	document.getElementById('playlist_cont').innerHTML = playList.getListHtml();
	playList.listItemActivate();
	playList.listItemSetActive( playList.curent );	
}

function playListPlay( playlist, incr, ind, pos ){
	if( !playlist || !playlist.list ) return;
	pos = pos || 0;
	incr = incr || 0;
	var oldcurr = playlist.curent,
		curr = playlist.curent+incr, 
		max = playlist.list.length-1 ;
	if( ind!=undefined ) curr = parseInt(ind);
	if( curr < 0 ) curr = max;
	if( curr>max ) curr = 0;
	playlist.curent = curr;

	playlist.listItemSetActive( curr );

	if(oldcurr != curr)
		mySound = createMySound( playlist.list[ curr ].src );
	mySound.playPause();
	mySound.setPosition( pos );
}

</script>
<body>

</body>
</html>
